'use strict';

const BaseService = require('../base');
const config  = require("../../../config/wx");
const path = require("path");
const fs = require("fs");
const crypto = require("crypto");
const dayjs = require("dayjs");
function generateNonceStr(len) {
  let data = "ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678";
  let str = "";
  for (let i = 0; i < len; i++) {
    str += data.charAt(Math.floor(Math.random() * data.length));
  }
  return str;
}
/**
 * 生成退款单号
 * @return {string}
 */
function generateRefundNo() {
  const now = dayjs();
  // 生成格式：年月日时分秒+4位随机数
  return 'RF' + now.format('YYYYMMDDHHmmss') + Math.floor(Math.random() * 10000).toString().padStart(4, '0');
}
class OrderRefundService extends BaseService {
  static get modelName() {
    return 'Business.OrderRefund';
  }
  createOrderSign(method, url, timestamp, nonce_str, order) {
    // 签名串
    let signStr = `${method}\n${url}\n${timestamp}\n${nonce_str}\n${JSON.stringify(
        order
    )}\n`;
    // 读取API证书文件内容 apiclient_key.pem的内容
    const filepath = path.join('app', '/public/apiclient_key.pem');
    let cert = fs.readFileSync(filepath, "utf-8");
    // 创建使用 RSA 算法和 SHA-256 散列算法的签名对象
    let sign = crypto.createSign("RSA-SHA256");
    // 对签名串进行加密处理
    sign.update(signStr);
    return sign.sign(cert, "base64");
  }

  /**
   * 处理退款
   * @param order_no
   * @param refund_remark
   * @param refund_amount
   * @param payment_amount
   * @returns {Promise<void>}
   */
  async processRefund({ order_no, refund_remark, refund_amount, payment_amount }) {
    try {
      const refund_no = generateRefundNo()
      console.log('refund_remark',refund_remark,Math.ceil(refund_amount * 100), Math.ceil(payment_amount * 100))
      let refundsParams = {
        out_trade_no: order_no,
        out_refund_no: refund_no,
        reason: refund_remark,
        notify_url: config.notify_url_refund,
        amount: {
          refund: Math.ceil(refund_amount * 100),
          total: Math.ceil(payment_amount * 100),
          currency: 'CNY'
        }
      }
      let timeStamp = Math.floor(new Date().getTime() / 1000)
      let nonceStr = generateNonceStr(32)
      const Authorization = `WECHATPAY2-SHA256-RSA2048 mchid="${config.mch_id}",nonce_str="${nonceStr}",signature="${this.createOrderSign('POST',
          '/v3/refund/domestic/refunds',
          timeStamp,
          nonceStr,
          refundsParams
      )}",timestamp="${timeStamp}",serial_no="${config.serial_no}"`

      const refundsRes = await this.ctx.curl('https://api.mch.weixin.qq.com/v3/refund/domestic/refunds', {
        method: "post",
        data: refundsParams,
        headers: {
          Authorization,
          Accept: 'application/json',
          'Content-Type': 'application/json',
        },
        dataType: 'json'
      })
      if (refundsRes.status === 200) {
        // 退款成功
        await this.ctx.model.Business.Order.update({
          refund_transaction_id: refundsRes.data.refund_id,
        }, {
          where: {
            order_no
          }
        });
      } else {
        await this.ctx.model.Business.Order.update({
          refund_result: refundsRes.data.message
        }, {
          where: {
            order_no
          }
        });
        throw new Error(refundsRes.data.message || '退款失败');
      }
    } catch (error) {
      throw error;
    }
  }
}

module.exports = OrderRefundService;
